//SPDX-FileCopyrightText: Copyright 2022-2024 深圳市同心圆网络有限公司
//SPDX-License-Identifier: GPL-3.0-only

package project_idea_api_serv

import (
	"context"
	"fmt"

	"atomgit.com/openlinksaas/api-server/api_common"
	"atomgit.com/openlinksaas/api-server/dao"
	"atomgit.com/openlinksaas/api-server/dao/idea_dao"
	"atomgit.com/openlinksaas/api-server/dao/project_dao"
	"atomgit.com/openlinksaas/proto-gen-go.git/events/events_idea"
	"atomgit.com/openlinksaas/proto-gen-go.git/events_api"
	"atomgit.com/openlinksaas/proto-gen-go.git/project_idea_api"
	"github.com/google/uuid"
	"go.mongodb.org/mongo-driver/mongo"
	"google.golang.org/protobuf/types/known/anypb"
)

func (apiImpl *ProjectIdeaApiImpl) addCreateIdeaEvent(
	sessionItem *dao.SessionDbItem,
	req *project_idea_api.CreateIdeaRequest,
	projectItem *project_dao.ProjectInfoDbItem,
	ideaId string, nowTime int64) {
	eventData, err := anypb.New(&events_idea.CreateIdeaEvent{
		IdeaId:      ideaId,
		Title:       req.BasicInfo.Title,
		KeywordList: req.BasicInfo.KeywordList,
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_IDEA,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_IDEA,
			RefId:           ideaId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectIdeaApiImpl) addUpateIdeaContentEvent(
	sessionItem *dao.SessionDbItem,
	req *project_idea_api.UpdateIdeaContentRequest,
	projectItem *project_dao.ProjectInfoDbItem,
	ideaItem *idea_dao.IdeaDbItem,
	nowTime int64) {

	eventData, err := anypb.New(&events_idea.UpdateIdeaContentEvent{
		IdeaId:   req.IdeaId,
		OldTitle: ideaItem.BasicInfo.Title,
		NewTitle: req.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_IDEA,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_IDEA,
			RefId:           req.IdeaId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectIdeaApiImpl) addUpdateIdeaKeywordEvent(
	sessionItem *dao.SessionDbItem,
	req *project_idea_api.UpdateIdeaKeywordRequest,
	projectItem *project_dao.ProjectInfoDbItem,
	ideaItem *idea_dao.IdeaDbItem, nowTime int64) {
	eventData, err := anypb.New(&events_idea.UpdateIdeaKeywordEvent{
		IdeaId:         ideaItem.IdeaId,
		Title:          ideaItem.BasicInfo.Title,
		OldKeywordList: ideaItem.BasicInfo.KeywordList,
		NewKeywordList: req.KeywordList,
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_IDEA,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_IDEA,
			RefId:           ideaItem.IdeaId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectIdeaApiImpl) addRemoveIdeaEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	ideaItem *idea_dao.IdeaDbItem, nowTime int64) {
	eventData, err := anypb.New(&events_idea.RemoveIdeaEvent{
		IdeaId: ideaItem.IdeaId,
		Title:  ideaItem.BasicInfo.Title,
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_IDEA,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_IDEA,
			RefId:           ideaItem.IdeaId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectIdeaApiImpl) addSetAppraiseEvent(
	sessionItem *dao.SessionDbItem,
	req *project_idea_api.SetAppraiseRequest,
	projectItem *project_dao.ProjectInfoDbItem,
	ideaItem *idea_dao.IdeaDbItem, nowTime int64) {
	eventData, err := anypb.New(&events_idea.SetAppraiseEvent{
		IdeaId:       ideaItem.IdeaId,
		Title:        ideaItem.BasicInfo.Title,
		AppriaseType: uint32(req.AppraiseType),
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_IDEA,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_IDEA,
			RefId:           ideaItem.IdeaId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectIdeaApiImpl) addCancelAppraiseEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	ideaItem *idea_dao.IdeaDbItem,
	appraiseItem *idea_dao.AppraiseDbItem,
	nowTime int64) {
	eventData, err := anypb.New(&events_idea.CancelAppraiseEvent{
		IdeaId:       ideaItem.IdeaId,
		Title:        ideaItem.BasicInfo.Title,
		AppriaseType: appraiseItem.AppraiseType,
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_IDEA,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_IDEA,
			RefId:           ideaItem.IdeaId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectIdeaApiImpl) addImportIdeaEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	ideaGroupId, name string, count uint32, nowTime int64) {
	eventData, err := anypb.New(&events_idea.ImportIdeaEvent{
		IdeaGroupId: ideaGroupId,
		Name:        name,
		Count:       count,
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_IDEA,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_PROJECT,
			RefId:           projectItem.ProjectId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}

func (apiImpl *ProjectIdeaApiImpl) addClearGroupEvent(
	sessionItem *dao.SessionDbItem,
	projectItem *project_dao.ProjectInfoDbItem,
	ideaGroupItem *idea_dao.IdeaGroupDbItem, nowTime int64) {
	eventData, err := anypb.New(&events_idea.ClearGroupEvent{
		IdeaGroupId: ideaGroupItem.IdeaGroupId,
		Title:       ideaGroupItem.Name,
	})
	if err != nil {
		fmt.Println(err)
		return
	}

	dbSess, err := dao.StartSession()
	if err != nil {
		fmt.Println(err)
		return
	}
	defer dao.EndSession(dbSess)
	dbSess.WithTransaction(context.Background(), func(sessCtx mongo.SessionContext) (interface{}, error) {
		err := api_common.AddEvent(sessCtx, &events_api.Event{
			EventId:         uuid.NewString(),
			UserId:          sessionItem.UserId,
			UserDisplayName: sessionItem.DisplayName,
			ProjectId:       projectItem.ProjectId,
			ProjectName:     projectItem.BasicInfo.ProjectName,
			EventType:       events_api.EVENT_TYPE_EVENT_TYPE_IDEA,
			EventTime:       nowTime,
			RefType:         events_api.EVENT_REF_TYPE_EVENT_REF_TYPE_PROJECT,
			RefId:           projectItem.ProjectId,
			EventData:       eventData,
		}, false, "", "")
		if err != nil {
			fmt.Println(err)
		}
		return nil, err
	})
}
